home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
netz
/
term
/
extras
/
source
/
term-source.lha
/
termBuffer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-15
|
29KB
|
1,435 lines
/*
** termBuffer.c
**
** Auxilary routines for text buffer/capture management.
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* Search string window gadgets. */
enum { GAD_STRING,GAD_OK,GAD_CANCEL };
/* Maximum size of an allocated line string. */
#define STRING_SIZE (1 + 255 + 1)
/* How many strings to include in a single puddle. */
#define STRING_COUNT 10
/* The number of lines the buffer will grow. */
#define BUFFER_GROW 100
/* Memory pool header. */
STATIC APTR BufferPoolHeader;
/* Word separator characters. */
STATIC BYTE WordSeparators[256] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0
};
/* AllocString(STRPTR String,WORD Len):
*
+ Allocate space for a string, new pooled version.
*/
STATIC STRPTR __regargs
AllocString(STRPTR String,LONG Len)
{
STRPTR Mem;
if(Len > 255)
Len = 255;
if(Mem = (STRPTR)LibAllocPooled(BufferPoolHeader,1 + Len + 1))
{
*Mem++ = Len;
if(Len)
CopyMem(String,Mem,Len);
Mem[Len] = 0;
return((STRPTR)Mem);
}
else
return(NULL);
}
/* FreeString(STRPTR String):
*
* Free the space occupied by a string, new pooled version.
*/
STATIC VOID __regargs
FreeString(STRPTR String)
{
LibFreePooled(BufferPoolHeader,&String[-1],1 + String[-1] + 1);
}
/* AddLine(STRPTR Line,LONG Size):
*
* Add a line to the display buffer.
*/
VOID __regargs
AddLine(register STRPTR Line,register LONG Size)
{
/*
while(Size > 0 && Line[Size - 1] == ' ')
Size--;
*/
/* Are we still to update the buffer contents? */
if(!BufferClosed)
{
/* Is the buffer array initialized? */
if(BufferLines)
{
ULONG Signals = 0;
/* Pick up the global access semaphore
* (two tasks are sharing the data).
*/
ObtainSemaphore(BufferSemaphore);
/* Check for limit. */
if(Config -> CaptureConfig -> MaxBufferSize && BufferSpace >= Config -> CaptureConfig -> MaxBufferSize)
{
register LONG i;
BufferSpace -= BufferLines[0][-1];
FreeString(BufferLines[0]);
for(i = 1 ; i < MaxLines ; i++)
BufferLines[i - 1] = BufferLines[i];
Lines--;
/* Tell the buffer task to
* refresh the display.
*/
Signals = SIG_MOVEUP;
}
else
{
/* We've reached the last line in the buffer. */
if(Lines == MaxLines)
{
STRPTR *MoreBuffer;
/* Allocate space for some more lines. */
if(MoreBuffer = (STRPTR *)AllocVecPooled((MaxLines + BUFFER_GROW) * sizeof(STRPTR),MEMF_ANY | MEMF_CLEAR))
{
register LONG i;
BufferChanged = TRUE;
/* Copy the old lines to the new
* buffer.
*/
for(i = 0 ; i < Lines ; i++)
MoreBuffer[i] = BufferLines[i];
/* Free the old lines. */
FreeVecPooled(BufferLines);
/* Set the new buffer. */
MaxLines += BUFFER_GROW;
BufferLines = MoreBuffer;
}
else
{
BufferChanged = TRUE;
/* We couldn't get enough memory
* to extend the number of lines
* in the buffer, so we'll have
* to wrap the contents of the
* buffer around.
*/
if(Lines)
{
register LONG i;
BufferSpace -= BufferLines[0][-1];
FreeString(BufferLines[0]);
for(i = 1 ; i < MaxLines ; i++)
BufferLines[i - 1] = BufferLines[i];
Lines--;
/* Tell the buffer task to
* refresh the display.
*/
Signals = SIG_MOVEUP;
}
}
}
}
/* Allocate a new line and copy the buffer contents
* into it.
*/
if(BufferLines[Lines] = AllocString(Line,Size))
{
BufferChanged = TRUE;
Lines++;
BufferSpace += Size;
}
ReleaseSemaphore(BufferSemaphore);
/* Tell the buffer task to update the display. */
if(!Signals)
{
Signals = SIG_UPDATE;
UpdateReview(FALSE);
}
else
UpdateReview(TRUE);
ObtainSemaphore(&BufferTaskSemaphore);
if(BufferTask && Signals)
{
Forbid();
ClrSignal(SIG_HANDSHAKE);
Signal(BufferTask,Signals);
Wait(SIG_HANDSHAKE);
Permit();
}
ReleaseSemaphore(&BufferTaskSemaphore);
}
}
}
/* DeleteBuffer():
*
* Delete buffer resources.
*/
VOID
DeleteBuffer()
{
if(BufferLines)
{
FreeVecPooled(BufferLines);
BufferLines = NULL;
}
if(BufferPoolHeader)
{
LibDeletePool(BufferPoolHeader);
BufferPoolHeader = NULL;
}
if(BufferSemaphore)
{
FreeVecPooled(BufferSemaphore);
BufferSemaphore = NULL;
}
}
/* CreateBuffer():
*
* Allocate buffer resources.
*/
BYTE
CreateBuffer()
{
if(BufferLines = (STRPTR *)AllocVecPooled(MaxLines * sizeof(STRPTR),MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC))
{
if(BufferSemaphore = (struct SignalSemaphore *)AllocVecPooled(sizeof(struct SignalSemaphore),MEMF_ANY | MEMF_PUBLIC))
{
InitSemaphore(BufferSemaphore);
/* Create a memory pool header if possible. */
if(BufferPoolHeader = LibCreatePool(MEMF_ANY | MEMF_PUBLIC,STRING_SIZE * STRING_COUNT,STRING_SIZE * STRING_COUNT))
return(TRUE);
}
FreeVecPooled(BufferLines);
BufferLines = NULL;
}
return(FALSE);
}
/* FreeBuffer():
*
* Release the contents of the text buffer.
*/
VOID
FreeBuffer()
{
/* Free the contents of the display buffer. */
if(BufferLines)
{
APTR NewPoolHeader;
ObtainSemaphore(BufferSemaphore);
/* If a new pool header is available, free the old
* pool and replace it with the new pool.
*/
if(NewPoolHeader = LibCreatePool(MEMF_ANY | MEMF_PUBLIC,STRING_SIZE * STRING_COUNT,STRING_SIZE * STRING_COUNT))
{
LibDeletePool(BufferPoolHeader);
BufferPoolHeader = NewPoolHeader;
}
else
{
LONG i;
for(i = 0 ; i < Lines ; i++)
{
if(BufferLines[i])
FreeString(BufferLines[i]);
}
}
FreeVecPooled(BufferLines);
Lines = 0;
MaxLines = BUFFER_GROW;
BufferLines = (STRPTR *)AllocVecPooled(MaxLines * sizeof(STRPTR),MEMF_ANY | MEMF_CLEAR);
ReleaseSemaphore(BufferSemaphore);
UpdateReview(TRUE);
}
BufferSpace = 0;
BufferChanged = FALSE;
}
/* DeleteSearchInfo(struct SearchInfo *Info):
*
* Free buffer allocated by CreateSearchInfo().
*/
VOID __regargs
DeleteSearchInfo(struct SearchInfo *Info)
{
if(Info)
FreeVecPooled(Info);
}
/* CreateSearchInfo(STRPTR Pattern):
*
* Create auxilary data required by SearchTextBuffer().
*/
struct SearchInfo * __regargs
CreateSearchInfo(STRPTR Pattern,BOOLEAN Forward,BOOLEAN IgnoreCase,BOOLEAN WholeWords)
{
struct SearchInfo *Info;
/* Allocate the buffer. */
if(Info = (struct SearchInfo *)AllocVecPooled(sizeof(struct SearchInfo),MEMF_ANY | MEMF_PUBLIC))
{
WORD i;
/* Determine pattern width. */
Info -> PatternWidth = strlen(Pattern);
Info -> IgnoreCase = IgnoreCase;
if(Info -> PatternWidth == 1)
{
if(WordSeparators[Pattern[0]])
WholeWords = FALSE;
}
Info -> WholeWords = WholeWords;
/* Turn the pattern into upper case characters. */
if(IgnoreCase)
{
for(i = 0 ; i <= Info -> PatternWidth ; i++)
Info -> Pattern[i] = ToUpper(Pattern[i]);
}
else
{
for(i = 0 ; i <= Info -> PatternWidth ; i++)
Info -> Pattern[i] = Pattern[i];
}
/* Fill the entire range with the maximum pattern width. */
for(i = 0 ; i < 256 ; i++)
Info -> Distance[i] = Info -> PatternWidth;
/* Fill in the matching distances. */
if(Forward)
{
for(i = 0 ; i < Info -> PatternWidth - 1 ; i++)
Info -> Distance[Info -> Pattern[i]] = Info -> PatternWidth - 1 - i;
}
else
{
for(i = Info -> PatternWidth - 1 ; i > 0 ; i--)
Info -> Distance[Info -> Pattern[i]] = i;
}
/* Restart from scratch. */
Info -> FoundY = -1;
Info -> Forward = Forward;
}
return(Info);
}
/* SearchTextBuffer():
*
* String search function, based on the Boyer-Moore search
* algorithm.
*/
LONG __regargs
SearchTextBuffer(struct SearchInfo *Info)
{
if(BufferLines)
{
UBYTE *Distance,
*Pattern;
WORD LineWidth,
PatternWidth;
STRPTR Line;
LONG i;
WORD SearchPosition,PatternIndex,LineIndex,LastSearchPosition;
/* Extract the relevant data. */
Distance = Info -> Distance;
Pattern = Info -> Pattern;
PatternWidth = Info -> PatternWidth;
if(Info -> WholeWords)
{
/* Which direction are we to search? */
if(Info -> IgnoreCase)
{
if(Info -> Forward)
{
/* Update the search positions. */
if(Info -> FoundY == -1)
{
Info -> FoundX = 0;
Info -> FoundY = 0;
LastSearchPosition = 0;
}
else
{
/* Proceed to the next line. */
if(!(LastSearchPosition = Info -> Index))
Info -> FoundY = (Info -> FoundY + 1) % Lines;
}
/* Run down the buffer. */
for(i = Info -> FoundY ; i < Lines ; i++)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Where are we to start searching? */
if(LastSearchPosition)
SearchPosition = LastSearchPosition;
else
SearchPosition = PatternWidth;
do
{
/* How many line characters
* match the pattern?
*/
PatternIndex = PatternWidth - 1;
LineIndex = SearchPosition - 1;
while(PatternIndex >= 0 && Pattern[PatternIndex] == ToUpper(Line[LineIndex]))
{
LineIndex--;
PatternIndex--;
}
/* Update the line search index
* for subsequent searches.
*/
SearchPosition += Distance[ToUpper(Line[SearchPosition - 1])];
/* Found the pattern? */
if(PatternIndex < 0)
{
LONG X = LineIndex + 1;
if(X)
{
if(!WordSeparators[Line[X - 1]])
continue;
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
}
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
/* Store the position. */
Info -> FoundX = LineIndex + 1;
Info -> FoundY = i;
/* Remember column to start
* next search attempt at.
*/
if(SearchPosition <= LineWidth)
Info -> Index = SearchPosition;
else
Info -> Index = 0;
return(i);
}
}
while(SearchPosition <= LineWidth);
}
/* Reset search column. */
LastSearchPosition = 0;
}
}
else
{
/* Update the search positions. */
if(Info -> FoundY == -1)
{
Info -> FoundX = 0;
Info -> FoundY = Lines - 1;
LastSearchPosition = 0;
}
else
{
if((LastSearchPosition = Info -> Index) < 1)
{
if(Info -> FoundY)
Info -> FoundY--;
else
Info -> FoundY = Lines - 1;
}
}
/* Run down the buffer. */
for(i = Info -> FoundY ; i >= 0 ; i--)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Cast the magic spell of Boyer-Moore... */
if(LastSearchPosition < 1)
SearchPosition = LineWidth - (PatternWidth - 1);
else
SearchPosition = LastSearchPosition;
do
{
PatternIndex = 0;
LineIndex = SearchPosition - 1;
while(PatternIndex < PatternWidth && Pattern[PatternIndex] == ToUpper(Line[LineIndex]))
{
LineIndex++;
PatternIndex++;
}
SearchPosition -= Distance[ToUpper(Line[SearchPosition - 1])];
if(PatternIndex == PatternWidth)
{
LONG X = LineIndex - PatternWidth;
if(X)
{
if(!WordSeparators[Line[X - 1]])
continue;
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
}
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
Info -> FoundX = LineIndex - PatternWidth;
Info -> FoundY = i;
Info -> Index = SearchPosition;
return(i);
}
}
while(SearchPosition > 0);
}
LastSearchPosition = 0;
}
}
}
else
{
if(Info -> Forward)
{
/* Update the search positions. */
if(Info -> FoundY == -1)
{
Info -> FoundX = 0;
Info -> FoundY = 0;
LastSearchPosition = 0;
}
else
{
/* Proceed to the next line. */
if(!(LastSearchPosition = Info -> Index))
Info -> FoundY = (Info -> FoundY + 1) % Lines;
}
/* Run down the buffer. */
for(i = Info -> FoundY ; i < Lines ; i++)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Where are we to start searching? */
if(LastSearchPosition)
SearchPosition = LastSearchPosition;
else
SearchPosition = PatternWidth;
do
{
/* How many line characters
* match the pattern?
*/
PatternIndex = PatternWidth - 1;
LineIndex = SearchPosition - 1;
while(PatternIndex >= 0 && Pattern[PatternIndex] == Line[LineIndex])
{
LineIndex--;
PatternIndex--;
}
/* Update the line search index
* for subsequent searches.
*/
SearchPosition += Distance[Line[SearchPosition - 1]];
/* Found the pattern? */
if(PatternIndex < 0)
{
LONG X = LineIndex + 1;
if(X)
{
if(!WordSeparators[Line[X - 1]])
continue;
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
}
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
/* Store the position. */
Info -> FoundX = LineIndex + 1;
Info -> FoundY = i;
/* Remember column to start
* next search attempt at.
*/
if(SearchPosition <= LineWidth)
Info -> Index = SearchPosition;
else
Info -> Index = 0;
return(i);
}
}
while(SearchPosition <= LineWidth);
}
/* Reset search column. */
LastSearchPosition = 0;
}
}
else
{
/* Update the search positions. */
if(Info -> FoundY == -1)
{
Info -> FoundX = 0;
Info -> FoundY = Lines - 1;
LastSearchPosition = 0;
}
else
{
if((LastSearchPosition = Info -> Index) < 1)
{
if(Info -> FoundY)
Info -> FoundY--;
else
Info -> FoundY = Lines - 1;
}
}
/* Run down the buffer. */
for(i = Info -> FoundY ; i >= 0 ; i--)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Cast the magic spell of Boyer-Moore... */
if(LastSearchPosition < 1)
SearchPosition = LineWidth - (PatternWidth - 1);
else
SearchPosition = LastSearchPosition;
do
{
PatternIndex = 0;
LineIndex = SearchPosition - 1;
while(PatternIndex < PatternWidth && Pattern[PatternIndex] == Line[LineIndex])
{
LineIndex++;
PatternIndex++;
}
SearchPosition -= Distance[Line[SearchPosition - 1]];
if(PatternIndex == PatternWidth)
{
LONG X = LineIndex - PatternWidth;
if(X)
{
if(!WordSeparators[Line[X - 1]])
continue;
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
}
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
Info -> FoundX = LineIndex - PatternWidth;
Info -> FoundY = i;
Info -> Index = SearchPosition;
return(i);
}
}
while(SearchPosition > 0);
}
LastSearchPosition = 0;
}
}
}
}
else
{
/* Which direction are we to search? */
if(Info -> IgnoreCase)
{
if(Info -> Forward)
{
/* Update the search positions. */
if(Info -> FoundY == -1)
{
Info -> FoundX = 0;
Info -> FoundY = 0;
LastSearchPosition = 0;
}
else
{
/* Proceed to the next line. */
if(!(LastSearchPosition = Info -> Index))
Info -> FoundY = (Info -> FoundY + 1) % Lines;
}
/* Run down the buffer. */
for(i = Info -> FoundY ; i < Lines ; i++)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Where are we to start searching? */
if(LastSearchPosition)
SearchPosition = LastSearchPosition;
else
SearchPosition = PatternWidth;
do
{
/* How many line characters
* match the pattern?
*/
PatternIndex = PatternWidth - 1;
LineIndex = SearchPosition - 1;
while(PatternIndex >= 0 && Pattern[PatternIndex] == ToUpper(Line[LineIndex]))
{
LineIndex--;
PatternIndex--;
}
/* Update the line search index
* for subsequent searches.
*/
SearchPosition += Distance[ToUpper(Line[SearchPosition - 1])];
/* Found the pattern? */
if(PatternIndex < 0)
{
/* Store the position. */
Info -> FoundX = LineIndex + 1;
Info -> FoundY = i;
/* Remember column to start
* next search attempt at.
*/
if(SearchPosition <= LineWidth)
Info -> Index = SearchPosition;
else
Info -> Index = 0;
return(i);
}
}
while(SearchPosition <= LineWidth);
}
/* Reset search column. */
LastSearchPosition = 0;
}
}
else
{
/* Update the search positions. */
if(Info -> FoundY == -1)
{
Info -> FoundX = 0;
Info -> FoundY = Lines - 1;
LastSearchPosition = 0;
}
else
{
if((LastSearchPosition = Info -> Index) < 1)
{
if(Info -> FoundY)
Info -> FoundY--;
else
Info -> FoundY = Lines - 1;
}
}
/* Run down the buffer. */
for(i = Info -> FoundY ; i >= 0 ; i--)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Cast the magic spell of Boyer-Moore... */
if(LastSearchPosition < 1)
SearchPosition = LineWidth - (PatternWidth - 1);
else
SearchPosition = LastSearchPosition;
do
{
PatternIndex = 0;
LineIndex = SearchPosition - 1;
while(PatternIndex < PatternWidth && Pattern[PatternIndex] == ToUpper(Line[LineIndex]))
{
LineIndex++;
PatternIndex++;
}
SearchPosition -= Distance[ToUpper(Line[SearchPosition - 1])];
if(PatternIndex == PatternWidth)
{
Info -> FoundX = LineIndex - PatternWidth;
Info -> FoundY = i;
Info -> Index = SearchPosition;
return(i);
}
}
while(SearchPosition > 0);
}
LastSearchPosition = 0;
}
}
}
else
{
if(Info -> Forward)
{
/* Update the search positions. */
if(Info -> FoundY == -1)
{
Info -> FoundX = 0;
Info -> FoundY = 0;
LastSearchPosition = 0;
}
else
{
/* Proceed to the next line. */
if(!(LastSearchPosition = Info -> Index))
Info -> FoundY = (Info -> FoundY + 1) % Lines;
}
/* Run down the buffer. */
for(i = Info -> FoundY ; i < Lines ; i++)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Where are we to start searching? */
if(LastSearchPosition)
SearchPosition = LastSearchPosition;
else
SearchPosition = PatternWidth;
do
{
/* How many line characters
* match the pattern?
*/
PatternIndex = PatternWidth - 1;
LineIndex = SearchPosition - 1;
while(PatternIndex >= 0 && Pattern[PatternIndex] == Line[LineIndex])
{
LineIndex--;
PatternIndex--;
}
/* Update the line search index
* for subsequent searches.
*/
SearchPosition += Distance[Line[SearchPosition - 1]];
/* Found the pattern? */
if(PatternIndex < 0)
{
/* Store the position. */
Info -> FoundX = LineIndex + 1;
Info -> FoundY = i;
/* Remember column to start
* next search attempt at.
*/
if(SearchPosition <= LineWidth)
Info -> Index = SearchPosition;
else
Info -> Index = 0;
return(i);
}
}
while(SearchPosition <= LineWidth);
}
/* Reset search column. */
LastSearchPosition = 0;
}
}
else
{
/* Update the search positions. */
if(Info -> FoundY == -1)
{
Info -> FoundX = 0;
Info -> FoundY = Lines - 1;
LastSearchPosition = 0;
}
else
{
if((LastSearchPosition = Info -> Index) < 1)
{
if(Info -> FoundY)
Info -> FoundY--;
else
Info -> FoundY = Lines - 1;
}
}
/* Run down the buffer. */
for(i = Info -> FoundY ; i >= 0 ; i--)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Cast the magic spell of Boyer-Moore... */
if(LastSearchPosition < 1)
SearchPosition = LineWidth - (PatternWidth - 1);
else
SearchPosition = LastSearchPosition;
do
{
PatternIndex = 0;
LineIndex = SearchPosition - 1;
while(PatternIndex < PatternWidth && Pattern[PatternIndex] == Line[LineIndex])
{
LineIndex++;
PatternIndex++;
}
SearchPosition -= Distance[Line[SearchPosition - 1]];
if(PatternIndex == PatternWidth)
{
Info -> FoundX = LineIndex - PatternWidth;
Info -> FoundY = i;
Info -> Index = SearchPosition;
return(i);
}
}
while(SearchPosition > 0);
}
LastSearchPosition = 0;
}
}
}
}
}
return(-1);
}
STATIC ULONG __asm __saveds
HistoryFunc(register __a0 struct Hook *Hook,register __a1 STRPTR NewString)
{
struct List *List = (struct List *)Hook -> h_Data;
if(NewString)
{
struct Node *Node = CreateNode(NewString);
if(Node)
AddTail(List,Node);
else
return(FALSE);
}
else
{
struct Node *Node = RemHead(List);
FreeNode(Node);
}
return(TRUE);
}
BOOLEAN __regargs
HandleSearchMessage(struct SearchContext *Context,struct IntuiMessage **MessagePtr)
{
struct IntuiMessage *Message;
BOOLEAN Done = FALSE;
if(Message = GT_FilterIMsg(*MessagePtr))
{
ULONG MsgClass = Message -> Class,
MsgQualifier = Message -> Qualifier;
struct Gadget *MsgGadget = (struct Gadget *)Message -> IAddress;
UWORD MsgCode = Message -> Code;
LT_HandleInput(Context -> SearchHandle,MsgQualifier,&MsgClass,&MsgCode,&MsgGadget);
if(MsgClass == IDCMP_CLOSEWINDOW)
Done = TRUE;
if(MsgClass == IDCMP_GADGETUP)
{
switch(MsgGadget -> GadgetID)
{
case GAD_STRING:
if(MsgCode == '\r')
{
if(Context -> LocalBuffer[0])
{
strcpy(Context -> Buffer,Context -> LocalBuffer);
Context -> Ok = TRUE;
LT_PressButton(Context -> SearchHandle,GAD_OK);
}
else
LT_PressButton(Context -> SearchHandle,GAD_CANCEL);
Done = TRUE;
}
break;
case GAD_OK:
LT_UpdateStrings(Context -> SearchHandle);
if(Context -> LocalBuffer[0])
{
strcpy(Context -> Buffer,Context -> LocalBuffer);
Context -> Ok = TRUE;
}
Done = TRUE;
break;
case GAD_CANCEL:
Done = TRUE;
break;
}
}
GT_PostFilterIMsg(Message);
}
ReplyMsg(*MessagePtr);
*MessagePtr = NULL;
return(Done);
}
VOID __regargs
DeleteSearchContext(struct SearchContext *Context)
{
if(Context)
{
LT_DeleteHandle(Context -> SearchHandle);
DISPOSE(Context);
}
}
struct SearchContext * __regargs
CreateSearchContext(struct Window *ParentWindow,STRPTR Buffer,struct Hook *HistoryHook,BOOLEAN *Forward,BOOLEAN *IgnoreCase,BOOLEAN *WholeWords)
{
struct SearchContext *Context;
if(NEW(Context))
{
struct LayoutHandle *Handle;
Context -> Buffer = Buffer;
if(HistoryHook)
HistoryHook -> h_Entry = (HOOKFUNC)HistoryFunc;
if(Handle = LT_CreateHandleTags(ParentWindow -> WScreen,
LH_LocaleHook, &LocaleHook,
TAG_DONE))
{
struct Window *Window;
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, HORIZONTAL_KIND,
// LA_LabelText, LocaleString(MSG_TERMBUFFER_ENTER_SEARCH_STRING_TXT),
TAG_DONE);
{
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, STRING_KIND,
LA_LabelID, MSG_V36_0788,
LA_STRPTR, Context -> LocalBuffer,
LA_Chars, 30,
LA_ID, GAD_STRING,
LAST_HistoryLines, MAX(Config -> CaptureConfig -> SearchHistory,1),
LAST_HistoryHook, HistoryHook,
GTST_MaxChars, 255,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type,YBAR_KIND,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, CHECKBOX_KIND,
LA_LabelID, MSG_TERMBUFFER_SEARCH_FORWARD_TXT,
LA_BYTE, Forward,
TAG_DONE);
LT_New(Handle,
LA_Type, CHECKBOX_KIND,
LA_LabelID, MSG_TEXTBUFFER_IGNORE_CASE_GAD,
LA_BYTE, IgnoreCase,
TAG_DONE);
LT_New(Handle,
LA_Type, CHECKBOX_KIND,
LA_LabelID, MSG_SEARCH_ONLY_WHOLE_WORDS_TXT,
LA_BYTE, WholeWords,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_EndGroup(Handle);
}
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,LA_Type,XBAR_KIND,LAXB_FullSize,TRUE,TAG_DONE);
LT_EndGroup(Handle);
}
LT_New(Handle,LA_Type,HORIZONTAL_KIND,
LAGR_SameSize, TRUE,
LAGR_Spread, TRUE,
TAG_DONE);
{
LT_New(Handle,
LA_Type, BUTTON_KIND,
LA_LabelID, MSG_TERMXPR_OKAY_GAD,
LA_ID, GAD_OK,
LABT_ReturnKey, TRUE,
LABT_ExtraFat, TRUE,
TAG_DONE);
LT_New(Handle,
LA_Type, BUTTON_KIND,
LA_LabelID, MSG_GLOBAL_CANCEL_GAD,
LA_ID, GAD_CANCEL,
LABT_EscKey, TRUE,
LABT_ExtraFat, TRUE,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_EndGroup(Handle);
}
if(Window = LT_Layout(Handle,LocaleString(MSG_TERMBUFFER_ENTER_SEARCH_STRING_TXT),NULL,0,0,IDCMP_CLOSEWINDOW,0,
LAWN_HelpHook, &GuideHook,
LAWN_Parent, ParentWindow,
LAWN_UserPort, ParentWindow -> UserPort,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_DragBar, TRUE,
WA_RMBTrap, TRUE,
WA_Activate, TRUE,
TAG_DONE))
{
LT_Activate(Handle,GAD_STRING);
Context -> SearchHandle = Handle;
Context -> SearchWindow = Window;
return(Context);
}
}
DISPOSE(Context);
}
return(NULL);
}